package com.shivaji;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.graphics.Bitmap;

public class MemoryCache {
	private final Map<String, WeakReference<Bitmap>> cache = new HashMap<String, WeakReference<Bitmap>>();
	private final Context context;

	/*
	 * IMPORTANT NOTE: This code is designed to demonstrate the concept of a
	 * memory cache and has deliberately been simplified to keep the technique
	 * clear. However, this will most likely cause
	 * ConcurrentModificatioExceptions to be thrown unless it is made thread
	 * safe.
	 */

	public MemoryCache(Context context) {
		/*
		 * We may have been given an Application context, but just in case let's
		 * request one to ensure that we don't associate our Bitmaps with an
		 * Activity Context which could result in a context leak.
		 */
		this.context = context.getApplicationContext();
	}

	@Override
	public String toString() {
		return "Cache size: " + cache.size();
	}

	public Bitmap getImage(String assetName) {
		WeakReference<Bitmap> ref = cache.get(assetName);
		Bitmap bitmap = ref == null ? null : ref.get();
		if (bitmap == null) {
			bitmap = Utils.loadAsset(context, assetName);
			if (bitmap != null) {
				cache.put(assetName, new WeakReference<Bitmap>(bitmap));
			}
		}
		return bitmap;
	}

	public boolean isCached(String assetName) {
		refreshCache();
		return cache.containsKey(assetName);
	}

	public void refreshCache() {
		List<String> removals = new LinkedList<String>();
		for (String key : cache.keySet()) 
		{
			WeakReference<Bitmap> bm = cache.get(key);
			if (bm.get() == null) {
				removals.add(key);
			}
		}
		for (String key : removals) {
			cache.remove(key);
		}
	}
}
